import { accountService } from '@/services/security/Account';
import { HttpUtil } from '@/utils/HttpUtil';
import { DateUtil } from '@/utils/DateUtil';
import settings, { defaultAvatar } from '@/settings';

const formatAccountInfo = info => {
	if (!info) {
		info = {};
	}
	if (!info.avatar) {
		info.avatar = '/api' + defaultAvatar;
	} else {
		info.avatar = '/api' + info.avatar;
	}
	if (!info.roles) {
		info.roles = [];
	}
	if (!info.accesses) {
		info.accesses = [];
	}
	if (!info.time) {
		info.time = DateUtil.format(new Date());
	}
	return info;
};

const getDefaultState = () => {
	return {
		token: null,
		info: formatAccountInfo()
	};
};

const state = getDefaultState();

const mutations = {
	RESET_STATE: state => {
		Object.assign(state, getDefaultState());
	},
	SET_TOKEN: (state, token) => {
		state.token = token;
	},
	SET_INFO: (state, info) => {
		state.info = info;
	}
};

const actions = {
	login({ commit, dispatch }, account) {
		return new Promise((resolve, reject) => {
			accountService
				.login(account)
				.then(resp => {
					const token = HttpUtil.getHeader(resp, 'Token');
					if (process.env.NODE_ENV === 'development' && settings.mock) {
						commit('SET_TOKEN', 'test-token');
					} else {
						commit('SET_TOKEN', token);
					}
					const info = formatAccountInfo(HttpUtil.getData(resp));
					commit('SET_INFO', info);
					if (settings.socket) {
						dispatch(
							'socket/connect',
							{ Authorization: token, ack: 'client' },
							{ root: true }
						)
							.then(({ frame }) => {
								console.log(frame);
							})
							.finally(() => {
								resolve(info);
							});
					} else {
						resolve(info);
					}
				})
				.catch(error => {
					reject(error);
				});
		});
	},
	logout({ commit, dispatch }) {
		return new Promise(resolve => {
			accountService
				.logout()
				.then(() => {
					commit('RESET_STATE');
					resolve();
				})
				.catch(error => {
					commit('RESET_STATE');
					resolve(error);
				})
				.finally(() => {
					if (settings.socket) {
						dispatch(
							'socket/disconnect',
							{ ack: 'client' },
							{ root: true }
						).then(({ frame }) => {
							console.log(frame);
						});
					}
				});
		});
	},
	upgrade({ commit }) {
		return new Promise((resolve, reject) => {
			accountService
				.upgradeInfo()
				.then(resp => {
					commit('SET_TOKEN', HttpUtil.getHeader(resp, 'token'));
					accountService
						.information()
						.then(resp => {
							const info = formatAccountInfo(HttpUtil.getData(resp));
							commit('SET_INFO', info);
							resolve(info);
						})
						.catch(error => {
							reject(error);
						});
				})
				.catch(error => {
					reject(error);
				});
		});
	}
};

export default {
	namespaced: true,
	state,
	mutations,
	actions
};
